package com.aditya.videoutil;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.aditya.videoutil.util.VideoUtilPathManager;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;

public class OutputActivity extends VideoActivity {

	File output;

	ArrayList<String> videos;

	boolean fromHome = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		String merged = getIntent().getStringExtra("ALREADY_MERGED");
		if ("y".equalsIgnoreCase(merged)) {
			output = new File(getIntent().getStringExtra("FILE_PATH"));
			showVideo();

		} else {
			videos = getIntent().getStringArrayListExtra("MERGE");

			output = VideoUtilPathManager.getNewFilePath("MERGE.mp4");
			fromHome = true;

			new Concatenate().execute();
		}

	}

	public void share(View view) {
		Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
		intent.setType("video/*");
		String shareBody = "Sharing " + output.getName();

		intent.putExtra(Intent.EXTRA_TEXT, shareBody);
		intent.putExtra(Intent.EXTRA_STREAM, output);

		try {
			startActivity(Intent.createChooser(intent, "Share via..."));
		} catch (ActivityNotFoundException e) {
			Toast.makeText(this, "No Application Available to share video",
					Toast.LENGTH_SHORT).show();
		}
	}

	public void delete(View view) {

		getAlertDialog()
				.setMessage("Are you sure to delete this video?")
				.setPositiveButton("Yes",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.dismiss();
								delete();
							}

						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				}).show();

	}

	protected void delete() {
		if (output.delete()) {
			Toast.makeText(this, output.getName() + " successfully deleted!",
					Toast.LENGTH_SHORT).show();
		} else {
			Toast.makeText(this, "Unable to delete " + output.getName(),
					Toast.LENGTH_SHORT).show();
		}

		Intent intent = new Intent(this, MyVideosActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		startActivity(intent);

	}

	public void play(View view) {
		Intent intent = new Intent(Intent.ACTION_VIEW).setDataAndType(
				Uri.fromFile(output), "video/mp4");
		try {
			startActivity(Intent.createChooser(intent, "Play video with..."));
		} catch (ActivityNotFoundException e) {
			Toast.makeText(this, "No Application Available to play video",
					Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.output, menu);
		return true;
	}

	private class Concatenate extends AsyncTask<String, Void, Boolean> {

		private ProgressDialog progressDialog;

		@Override
		protected void onPreExecute() {
			progressDialog = new ProgressDialog(OutputActivity.this);
			progressDialog
					.setMessage("It takes time to do the big things, please wait...");
			progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			progressDialog.show();

		}

		@Override
		protected void onPostExecute(Boolean result) {
			if (progressDialog != null && progressDialog.isShowing())
				progressDialog.dismiss();
			showVideo();
		}

		@Override
		protected Boolean doInBackground(String... params) {
			Container out = null;
			FileChannel fc = null;
			try {
				Movie[] inMovies = new Movie[videos.size()];
				for (int i = 0; i < videos.size(); i++) {
					inMovies[i] = MovieCreator.build(videos.get(i));
				}

				List<Track> videoTracks = new LinkedList<Track>();
				List<Track> audioTracks = new LinkedList<Track>();

				for (Movie m : inMovies) {
					for (Track t : m.getTracks()) {
						if (t.getHandler().equals("soun")) {
							audioTracks.add(t);
						}
						if (t.getHandler().equals("vide")) {
							videoTracks.add(t);
						}
					}
				}

				Movie result = new Movie();

				if (audioTracks.size() > 0) {
					result.addTrack(new AppendTrack(audioTracks
							.toArray(new Track[audioTracks.size()])));
				}
				if (videoTracks.size() > 0) {
					result.addTrack(new AppendTrack(videoTracks
							.toArray(new Track[videoTracks.size()])));
				}

				out = new DefaultMp4Builder().build(result);

				fc = new RandomAccessFile(output, "rw").getChannel();
				out.writeContainer(fc);

			} catch (IOException e) {
				Log.e("ERROR", "Exception while concatenating videos...", e);
			} finally {
				if (fc != null) {
					try {
						fc.close();
					} catch (IOException e) {
					}
				}

			}
			return true;
		}
	}

	public void rename(View v) {
		String name = ((EditText) findViewById(R.id.video_name)).getText()
				.toString();
		if (output.renameTo(new File(output.getParentFile(), name))) {
			Toast.makeText(this, "File successfully renamed to " + name,
					Toast.LENGTH_SHORT).show();

		} else {
			Toast.makeText(
					this,
					"Unable to rename - check if other programs are using the same file!",
					Toast.LENGTH_SHORT).show();

		}

	}

	public void showVideo() {
		setContentView(R.layout.activity_output);

		Bitmap thumbnail = ThumbnailUtils
				.createVideoThumbnail(output.getAbsolutePath(),
						MediaStore.Video.Thumbnails.MINI_KIND);

		int width = getWindowManager().getDefaultDisplay().getWidth() / 2;
		Bitmap resizedbitmap = Bitmap.createScaledBitmap(thumbnail, width,
				width, true);

		((ImageView) findViewById(R.id.output_video))
				.setImageBitmap(resizedbitmap);
		((EditText) findViewById(R.id.video_name)).setText(output.getName());
	}

	@Override
	public void onBackPressed() {
		if (fromHome) {
			Intent intent = new Intent(this, VideoUtilHomeActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
		} else {
			super.onBackPressed();
		}

	}
}
